package com.takeoff.iot.modbus.netty.message;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ruoyi.common.modbus.data.MiiData;
import com.ruoyi.common.modbus.data.MiiHmLocationData;
import com.ruoyi.common.modbus.factory.MiiDataFactory;
import com.ruoyi.common.modbus.message.MiiMessage;
import com.ruoyi.common.modbus.utils.CacheObjectUtils;
import com.ruoyi.common.modbus.utils.CacheUtils;
import com.ruoyi.common.modbus.utils.IntegerToByteUtil;
import com.ruoyi.common.modbus.utils.ModbusCrc16Utils;

import com.takeoff.iot.modbus.netty.channel.MiiChannel;
import com.takeoff.iot.modbus.netty.device.MiiDeviceChannel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.bouncycastle.util.encoders.Hex;

import io.netty.handler.codec.DecoderException;

/**
 * 类功能说明：对接收到的指令数据进行校验<br/>
 * 公司名称：未可自动化 <br/>
 * 作者：weikeauto <br/>
 */
@Slf4j
public class MiiInMessage implements MiiMessage {

    private String deviceGroup;
    private byte[] msg;
    private MiiData data;

    private int command;
    private int slaveAddress;

    public MiiInMessage(byte[] msg, MiiDataFactory dataFactory) {
        this(null, msg, dataFactory);
    }

    public MiiInMessage(MiiChannel miiChannel, byte[] msg, MiiDataFactory dataFactory) {
        MiiDeviceChannel miiDeviceChannel = (MiiDeviceChannel) miiChannel;
        this.deviceGroup = String.valueOf(miiDeviceChannel.port());
        this.msg = msg;
        byte[] startBytes = {msg[0]};
        byte[] linshi = {msg[1]};
        byte[] endBytes = {msg[msg.length - 1]};
        if (Arrays.equals(HEART_BEGIN_BYTES, startBytes) && Arrays.equals(HEART_BEGIN_BYTES, endBytes)) {
            // 如果是心跳
            byte[] datas = ArrayUtils.subarray(msg, 1, msg.length - 1);
            this.data = dataFactory.buildData(HEARTBEAT, datas);
            command = HEARTBEAT;
            // 讲会话放入缓存
//            String snStr = Hex.toHexString(msg);
//            String sn = qudiao(snStr);
//            String lastSn = convertFromHex(sn);
//			String sn = hexStringToString(Hex.toHexString(datas));
//			CacheUtils.put(sn, miiChannel,120000l);
//            CacheObjectUtils.put(miiChannel,sn);
		} else if (Arrays.equals(REGNO_BEGIN_BYTES, startBytes) && Arrays.equals(REGNO_BEGIN_BYTES, endBytes)) {
            // 如果是注册
            byte[] datas = ArrayUtils.subarray(msg, 1, msg.length - 1);
            this.data = dataFactory.buildData(REGNO, datas);
            command = REGNO;
        } else {
//			Pattern pattern = Pattern.compile("\\+LBS:(\\d+),(\\d+)");
            Pattern pattern = Pattern.compile("\\+LBS:(\"?[a-zA-Z0-9]+\"?),(\"?[a-zA-Z0-9]+\"?)");
//			byte[] byteArray = new BigInteger(Hex.toHexString(msg), 16).toByteArray();
            String utf8String = new String(msg);
            log.info("指令字符串=" + utf8String);
            Matcher matcher = pattern.matcher(utf8String);
            if (matcher.find()) {
                log.info("已进入设置到监听器" + utf8String);
                MiiHmLocationData miiHmLocationData = new MiiHmLocationData(msg);
//				long baseStationId = Long.parseLong(matcher.group(1));
//				long networkCode = Integer.parseInt(matcher.group(2));
                miiHmLocationData.setLac(matcher.group(2));
                miiHmLocationData.setCellId(matcher.group(1));
                this.data = miiHmLocationData;
                command = LOCATION;
            } else {
                byte[] datas = ArrayUtils.subarray(msg, DATA_INDEX, msg.length - 2);
                byte[] dataLength = ArrayUtils.subarray(msg, DATA_LENGTH_INDEX, DATA_INDEX);
//			if (datas.length != IntegerToByteUtil.bytesToInt(dataLength)) {
//				throw new DecoderException(String.format("报文长短异常:%s", Hex.toHexString(msg)));
//			}
//			byte[] checkcode = {msg[msg.length - 2], msg[msg.length - 1]};
//			byte[] checkData = ArrayUtils.subarray(msg, DEVICE_INDEX, msg.length - 2);
//			if (!ModbusCrc16Utils.getCrcString(checkData).equals(Hex.toHexString(checkcode))) {
//				throw new DecoderException(String.format("报文校验码校验错误:%s", Hex.toHexString(msg)));
//			}
//		int command = msg[COMMAND_INDEX] & 0x7F;
                slaveAddress = msg[0];
                byte[] funCode = {msg[1]};
                this.data = dataFactory.buildData(IOTDATA, datas);
//			if(Arrays.equals(FUN_CODE_03, funCode)){
                command = IOTDATA;
//			}
            }
        }
    }

	public static String hexStringToString(String hex) {
		byte[] bytes = new byte[hex.length() / 2];
		for (int i = 0; i < hex.length(); i += 2) {
			bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16));
		}
		return new String(bytes);
	}

    private String qudiao(String result) {
        // 去掉开头的"aa"
        if (result.startsWith("aa")) {
            result = result.substring(2);
        }

        // 去掉结尾的"aa"
        if (result.endsWith("aa")) {
            result = result.substring(0, result.length() - 2);
        }
        return result;
    }

    public static String convertFromHex(String hexString) {
        StringBuilder result = new StringBuilder();

        // 每2个字符一组进行处理（因为一个字节用2个16进制字符表示）
        for (int i = 0; i < hexString.length(); i += 2) {
            // 提取两个16进制字符
            String hexPair = hexString.substring(i, Math.min(i + 2, hexString.length()));

            // 将16进制转换为十进制，然后转换为字符
            int charCode = Integer.parseInt(hexPair, 16);
            result.append((char) charCode);
        }

        return result.toString();
    }

    public static void main1(String[] args) {
        byte[] data = Hex.decode("01030000000A");
        byte[] code = Hex.decode("C5CD");
//		byte[] data = Hex.decode("00000001");

//		byte[] msg = Hex.decode("0103140000000100000002000000030000000400000005D086");
//		byte[] datas = ArrayUtils.subarray(msg, DATA_INDEX, msg.length - 2);
//		byte[] dataLength = ArrayUtils.subarray(msg, DATA_LENGTH_INDEX, DATA_INDEX);
//		if (datas.length != IntegerToByteUtil.bytesToInt(dataLength)) {
//			throw new DecoderException(String.format("报文长短异常:%s", Hex.toHexString(msg)));
//		}
//
//		byte[] checkcode = {msg[msg.length - 2],msg[msg.length - 1]};
//		byte[] checkData = ArrayUtils.subarray(msg, DEVICE_INDEX, msg.length - 2);

        if (!ModbusCrc16Utils.getCrcString(data).equals(Hex.toHexString(code))) {
            throw new DecoderException(String.format("报文校验码校验错误:%s", Hex.toHexString(code)));
        }
//		01030600ff0000426a85ee
//		01031400ff0000426acc020000000000000000000000001657
        String hexString = "10000";
        int intBits = Integer.parseInt(hexString, 16);
        System.out.println(intBits);
        System.out.println(Float.intBitsToFloat(intBits));

    }

    public static void main(String[] args) {
        // 5745494b450d0a2b4c42533a33343731393130382c35383138360d0a4f4b0d0a
        // 0d0a2b4c42533a2245333441222c223035463644343442220d0a0d0a
        // 5745494b450d0a2b4c42533a36363332383635342c35383138360d0a4f4b0d0a
        String hexString = "5745494b450d0a2b4c42533a33343731393130382c35383138360d0a4f4b0d0a"; // 例如：Hello World的UTF-8编码
        byte[] byteArray = new BigInteger(hexString, 16).toByteArray();
        String utf8String = new String(byteArray);
        System.out.println(utf8String); // 输出: Hello World

        int decimal = Integer.parseInt("E34A", 16);
        System.out.println(decimal); // 输出: Hello World

        Pattern pattern = Pattern.compile("\\+LBS:(\"?[a-zA-Z0-9]+\"?),(\"?[a-zA-Z0-9]+\"?)");
//			Pattern pattern = Pattern.compile("\\+LBS:(\\d+),(\\d+)");
        Matcher matcher = pattern.matcher(utf8String);
        if (matcher.find()) {
            log.info("已进入设置到监听器" + utf8String);
            System.out.println(matcher.group(2));
            System.out.println(matcher.group(1));

        }
    }


    public String deviceGroup() {
        return deviceGroup;
    }

    @Override
    public int slaveAddress() {
        return slaveAddress;
    }

    public int command() {
        return command;
    }

    public int length() {
        byte[] dataLength = ArrayUtils.subarray(msg, DATA_INDEX, 1);
        return IntegerToByteUtil.bytesToInt(dataLength);
    }

    public MiiData data() {
        return data;
    }

    public int type() {
        return RECV;
    }

    public byte[] toBytes() {
        return msg;
    }
}
